package controllers

import (
	"encoding/json"
	"errors"
	beego "github.com/beego/beego/v2/server/web"
	"github.com/redis/go-redis/v9"
	"gorm.io/gorm"
	"log"
	"mime/multipart"
	"path/filepath"
	"qidian/models"
	"time"
)

type NovelController struct {
	beego.Controller
}

type Res struct {
	Code int         `json:"code"`
	Msg  string      `json:"msg"`
	Data interface{} `json:"data"`
}

func (c *NovelController) Add() {
	Title := c.GetString("title")
	Cate := c.GetString("cate")
	Author := c.GetString("author")
	Img := c.GetString("img")

	if Title == "" || Cate == "" || Author == "" || Img == "" {
		c.Data["json"] = Res{
			Code: 0,
			Msg:  "请确保所有字段不为空",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	}

	novel := models.Novel{
		Model:  gorm.Model{},
		Title:  Title,
		Cate:   Cate,
		Author: Author,
		Img:    Img,
	}

	err := models.DB.Create(&novel).Error
	if err != nil {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "添加失败",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	} else {
		c.Data["json"] = Res{
			Code: 200,
			Msg:  "添加成功",
			Data: nil,
		}
		_ = c.ServeJSON()
	}

}

func (c *NovelController) Upload() {
	img, header, err := c.GetFile("img")
	if err != nil {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "图片获取失败",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	}
	defer func(img multipart.File) {
		err = img.Close()
		if err != nil {

		}
	}(img)
	log.Println(header.Size)
	if (header.Size / 1024 / 1024) > 5 {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "图片大小限制5MB",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	}
	ImgType := map[string]bool{
		".jpg": true,
		".png": true,
	}

	if !ImgType[filepath.Ext(header.Filename)] {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "图片格式限制为jpg、png",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	}
	path := "static/img/" + header.Filename
	err = c.SaveToFile("img", path)
	if err != nil {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "图片保存失败",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	} else {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "图片保存成功",
			Data: "http://127.0.0.1:8080/" + path,
		}
		_ = c.ServeJSON()
	}
}

func (c *NovelController) List() {
	var novels []models.Novel
	// 1.先从redis中获取数据
	res, err := models.Rdb.Get(models.Ctx, "novel:list").Result()
	if err != nil {
		if !errors.Is(err, redis.Nil) {
			c.Data["json"] = Res{
				Code: 500,
				Msg:  "数据获取失败",
				Data: err,
			}
			_ = c.ServeJSON()
			return
		}
	}
	// 2.如果redis中没有数据
	if res == "" {
		log.Println("数据库获取数据")
		// 从数据库获取数据，并存入redis
		// 从数据库中获取数据
		err = models.DB.Find(&novels).Error
		if err != nil {
			c.Data["json"] = Res{
				Code: 500,
				Msg:  "数据获取失败",
				Data: nil,
			}
			_ = c.ServeJSON()
			return
		}
		//将mysql获取的数据存入redis
		//序列化数据为json
		JsonRes, JsonErr := json.Marshal(novels)
		if JsonErr != nil {
			c.Data["json"] = Res{
				Code: 500,
				Msg:  "数据转换失败",
				Data: nil,
			}
			_ = c.ServeJSON()
			return
		}
		//将序列化数据存入redis
		err = models.Rdb.Set(models.Ctx, "novel:list", JsonRes, time.Hour*24).Err()
		if err != nil {
			c.Data["json"] = Res{
				Code: 500,
				Msg:  "数据缓存失败",
				Data: nil,
			}
			_ = c.ServeJSON()
			return
		} else {
			c.Data["json"] = Res{
				Code: 200,
				Msg:  "数据获取成功",
				Data: novels,
			}
			_ = c.ServeJSON()
		}
	} else {
		log.Println("redis获取数据")
		//redis中有数据，直接返回
		//先进行反序列化
		err = json.Unmarshal([]byte(res), &novels)
		if err != nil {
			c.Data["json"] = Res{
				Code: 500,
				Msg:  "数据转换失败",
				Data: nil,
			}
			_ = c.ServeJSON()
			return
		} else {
			c.Data["json"] = Res{
				Code: 200,
				Msg:  "数据获取成功",
				Data: novels,
			}
			_ = c.ServeJSON()
		}
	}
}

func (c *NovelController) Del() {
	id := c.GetString("id")
	err := models.DB.Delete(&models.Novel{}, id).Error
	if err != nil {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "删除失败",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	} else {
		c.Data["json"] = Res{
			Code: 200,
			Msg:  "删除成功",
			Data: nil,
		}
		_ = c.ServeJSON()
	}
}

func (c *NovelController) Info() {
	id := c.GetString("id")
	var novel models.Novel
	err := models.DB.Where("id = ?", id).First(&novel).Error
	if err != nil {
		c.Data["json"] = Res{
			Code: 500,
			Msg:  "数据查询失败",
			Data: nil,
		}
		_ = c.ServeJSON()
		return
	} else {
		c.Data["json"] = Res{
			Code: 200,
			Msg:  "数据查询成功",
			Data: novel,
		}
		_ = c.ServeJSON()
	}
}
